package com.rear.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.BreakIterator;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtil {
	private static final char[] a = "&quot;".toCharArray();
	private static final char[] b = "&amp;".toCharArray();
	private static final char[] c = "&lt;".toCharArray();
	private static final char[] d = "&gt;".toCharArray();
	private static MessageDigest e = null;

	private static Random f = new Random();
	private static char[] g = "0123456789abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
			.toCharArray();
	private static final char[] h = "0000000000000000".toCharArray();
	public static final String EMPTY_STRING = "";
	public static final char DOT = 46;
	public static final char UNDERSCORE = 95;
	public static final String COMMA_SPACE = ", ";
	public static final String COMMA = ",";
	public static final String OPEN_PAREN = "(";
	public static final String CLOSE_PAREN = ")";
	public static final String EMPTY = "";

	public static String transHump2Underline(String param) {
		Pattern p = Pattern.compile("[A-Z]");
		if ((param == null) || (param.equals(""))) {
			return "";
		}
		StringBuffer sb = new StringBuffer(param);
		Matcher mc = p.matcher(param);
		int i = 0;
		while (mc.find()) {
			sb.replace(mc.start() + i, mc.end() + i, "_"
					+ mc.group().toLowerCase());
			++i;
		}

		if ('_' == sb.charAt(0)) {
			sb.deleteCharAt(0);
		}
		return sb.toString();
	}

	public static String tranUnderline2Hump(String param) {
		String[] _ary = param.split("_");
		StringBuffer strBuilder = new StringBuffer();
		for (int i = 0; i < _ary.length; ++i) {
			String str = _ary[i];
			if ((!("".equals(str))) && (i > 0)) {
				StringBuffer _builder = new StringBuffer();
				str = str.substring(0, 1).toUpperCase() + str.substring(1);
			}
			strBuilder.append(str);
		}
		return strBuilder.toString();
	}

	public static String format(String str, String[] args) {
		if (str.indexOf("%s") != -1) {
			str = a(str, args);
		}
		return MessageFormat.format(str, args);
	}

	private static String a(String str, String[] args) {
		if (args == null) {
			return str;
		}
		for (int i = 0; i < args.length; ++i) {
			if ((args[i] == null) || (str.indexOf("%s") == -1))
				continue;
			str = str.replaceFirst("\\%s", args[i]);
		}

		return str;
	}

	public static boolean isEmpty(String str) {
		return ((str == null) || (str.length() == 0));
	}

	public static boolean isNotEmpty(String str) {
		return (!(isEmpty(str)));
	}

	public static boolean isBlank(String str) {
		int strLen;
		if ((str == null) || ((strLen = str.length()) == 0)) {
			return true;
		}
		for (int i = 0; i < strLen; ++i) {
			if (!(Character.isWhitespace(str.charAt(i)))) {
				return false;
			}
		}
		return true;
	}

	public static String blankStr(String str, String defalutStr) {
		if (defalutStr == null) {
			defalutStr = "";
		}
		if (str == null) {
			return defalutStr;
		}
		return str.trim();
	}

	public static String blankStr(String str) {
		return blankStr(str, null);
	}

	public static boolean isNotBlank(String str) {
		return (!(isBlank(str)));
	}

	public static String convertCastChar(String src) {
		if ((src == null) || (src.equals(""))) {
			return src;
		}
		int length = src.length();
		StringBuffer tmp = new StringBuffer();
		for (int i = 0; i < length; ++i) {
			switch (src.charAt(i)) {
			case '%':
			case '\\':
			case '_':
				tmp.append("\\");
			}

			tmp.append(src.charAt(i));
		}
		return tmp.toString();
	}

	public static String convertForHtml(String src) {
		if ((src == null) || (src.equals(""))) {
			return src;
		}
		int length = src.length();
		StringBuffer tmp = new StringBuffer();
		for (int i = 0; i < length; ++i) {
			switch (src.charAt(i)) {
			case '<':
				tmp.append("&lt;");
				break;
			case '>':
				tmp.append("&gt;");
				break;
			case '"':
				tmp.append("&quot;");
				break;
			case ' ':
				int spaceCount = 0;
				for (; src.charAt(i) == ' '; ++spaceCount)
					++i;

				for (int j = 0; j < spaceCount / 2; ++j) {
					tmp.append("　");
				}
				if (spaceCount % 2 != 0) {
					tmp.append("&#160;");
				}
				--i;
				break;
			case '\n':
				tmp.append("<br/>");
				break;
			case '&':
				tmp.append("&amp;");
				break;
			case '\r':
				break;
			default:
				tmp.append(src.charAt(i));
			}
		}

		return tmp.toString();
	}

	public static String convertForXml(String src) {
		if ((src == null) || (src.equals(""))) {
			return src;
		}
		int length = src.length();
		StringBuffer tmp = new StringBuffer();
		for (int i = 0; i < length; ++i) {
			switch (src.charAt(i)) {
			case '<':
				tmp.append("&lt;");
				break;
			case '>':
				tmp.append("&gt;");
				break;
			case '"':
				tmp.append("&quot;");
				break;
			case ' ':
				int spaceCount = 0;
				for (; src.charAt(i) == ' '; ++spaceCount)
					++i;

				for (int j = 0; j < spaceCount / 2; ++j) {
					tmp.append("　");
				}
				if (spaceCount % 2 != 0) {
					tmp.append("&#160;");
				}
				--i;
				break;
			case '&':
				tmp.append("&amp;");
				break;
			case '\r':
				break;
			default:
				tmp.append(src.charAt(i));
			}
		}

		return tmp.toString();
	}

	public static String convertSingleQuot(String src) {
		if ((src == null) || (src.equals(""))) {
			return src;
		}
		int length = src.length();
		StringBuffer tmp = new StringBuffer();
		for (int i = 0; i < length; ++i) {
			if (src.charAt(i) == '\'')
				tmp.append("''");
			else {
				tmp.append(src.charAt(i));
			}
		}
		return tmp.toString();
	}

	public static String replace(String src, String mod, String str) {
		if ((src == null) || (src.length() == 0)) {
			return src;
		}
		if ((mod == null) || (mod.length() == 0)) {
			return src;
		}
		if (src == null) {
			src = "";
		}
		StringBuffer buffer = new StringBuffer();
		int idx1 = 0;
		int idx2 = 0;
		while ((idx2 = src.indexOf(mod, idx1)) != -1) {
			buffer.append(src.substring(idx1, idx2)).append(str);
			idx1 = idx2 + mod.length();
		}
		buffer.append(src.substring(idx1));
		return buffer.toString();
	}


	public static String replaceOnce(String template, String placeholder,
			String replacement) {
		int loc = template.indexOf(placeholder);
		if (loc < 0) {
			return template;
		}
		return template.substring(0, loc) + replacement
				+ template.substring(loc + placeholder.length());
	}

	public static final String escapeHTMLTags(String in) {
		if (in == null)
			return null;
		int i = 0;
		int last = 0;
		char[] input = in.toCharArray();
		int len = input.length;
		StringBuffer out = new StringBuffer((int) (len * 1.3D));
		for (; i < len; ++i) {
			char ch = input[i];
			if (ch <= '>') {
				if (ch == '<') {
					if (i > last)
						out.append(input, last, i - last);
					last = i + 1;
					out.append(c);
				} else if (ch == '>') {
					if (i > last)
						out.append(input, last, i - last);
					last = i + 1;
					out.append(d);
				}
			}
		}
		if (last == 0)
			return in;
		if (i > last)
			out.append(input, last, i - last);
		return out.toString();
	}

	public static final String escapeNull(String str) {
		return ((str == null) ? "" : str);
	}

	public static final String escapeForXML(String string) {
		if (string == null)
			return null;
		int i = 0;
		int last = 0;
		char[] input = string.toCharArray();
		int len = input.length;
		StringBuffer out = new StringBuffer((int) (len * 1.3D));
		for (; i < len; ++i) {
			char ch = input[i];
			if (ch <= '>') {
				if (ch == '<') {
					if (i > last)
						out.append(input, last, i - last);
					last = i + 1;
					out.append(c);
				} else if (ch == '&') {
					if (i > last)
						out.append(input, last, i - last);
					last = i + 1;
					out.append(b);
				} else if (ch == '"') {
					if (i > last)
						out.append(input, last, i - last);
					last = i + 1;
					out.append(a);
				}
			}
		}
		if (last == 0)
			return string;
		if (i > last)
			out.append(input, last, i - last);
		return out.toString();
	}

	public static final String unescapeFromXML(String string) {
		string = replace(string, "&lt;", "<");
		string = replace(string, "&gt;", ">");
		string = replace(string, "&quot;", "\"");
		return replace(string, "&amp;", "&");
	}

	public static String[] split(String src, String delim) {
		if ((src == null) || (delim == null)) {
			return null;
		}
		StringTokenizer st = new StringTokenizer(src, delim);
		Vector vct = new Vector();
		while (st.hasMoreTokens()) {
			vct.add(st.nextToken());
		}
		Object[] tks = vct.toArray();
		String[] rt = new String[vct.size()];
		System.arraycopy(tks, 0, rt, 0, vct.size());
		return rt;
	}

	public static final synchronized String hash(String data) {
		if (e == null)
			try {
				e = MessageDigest.getInstance("MD5");
			} catch (NoSuchAlgorithmException nsae) {
				System.err
						.println("Failed to load the MD5 MessageDigest. Jive will be unable to function normally.");

				nsae.printStackTrace();
			}
		e.update(data.getBytes());
		return encodeHex(e.digest());
	}

	public static final String encodeHex(byte[] bytes) {
		StringBuffer buf = new StringBuffer(bytes.length * 2);
		for (int i = 0; i < bytes.length; ++i) {
			if ((bytes[i] & 0xFF) < 16)
				buf.append("0");
			buf.append(Long.toString(bytes[i] & 0xFF, 16));
		}

		return buf.toString();
	}

	public static final byte[] decodeHex(String hex) {
		char[] chars = hex.toCharArray();
		byte[] bytes = new byte[chars.length / 2];
		int byteCount = 0;
		for (int i = 0; i < chars.length; i += 2) {
			byte newByte = 0;
			newByte = (byte) (newByte | a(chars[i]));
			newByte = (byte) (newByte << 4);
			newByte = (byte) (newByte | a(chars[(i + 1)]));
			bytes[byteCount] = newByte;
			++byteCount;
		}

		return bytes;
	}

	public static String encodeBase64(String data) {
		return encodeBase64(data.getBytes());
	}

	public static String encodeBase64(byte[] data) {
		int len = data.length;
		StringBuffer ret = new StringBuffer((len / 3 + 1) * 4);
		for (int i = 0; i < len; ++i) {
			int c = data[i] >> 2 & 0x3F;
			ret.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
					.charAt(c));
			c = data[i] << 4 & 0x3F;
			if (++i < len)
				c |= data[i] >> 4 & 0xF;
			ret.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
					.charAt(c));
			if (i < len) {
				c = data[i] << 2 & 0x3F;
				if (++i < len)
					c |= data[i] >> 6 & 0x3;
				ret.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
						.charAt(c));
			} else {
				++i;
				ret.append('=');
			}
			if (i < len) {
				c = data[i] & 0x3F;
				ret.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
						.charAt(c));
			} else {
				ret.append('=');
			}
		}

		return ret.toString();
	}

	public static String decodeBase64(String data) {
		return decodeBase64(data.getBytes());
	}

	public static String decodeBase64(byte[] data) {
		int len = data.length;
		StringBuffer ret = new StringBuffer(len * 3 / 4);
		for (int i = 0; i < len; ++i) {
			int c = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
					.indexOf(data[i]);
			++i;
			int c1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
					.indexOf(data[i]);
			c = c << 2 | c1 >> 4 & 0x3;
			ret.append((char) c);
			if (++i < len) {
				c = data[i];
				if (61 == c)
					break;
				c = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
						.indexOf((char) c);
				c1 = c1 << 4 & 0xF0 | c >> 2 & 0xF;
				ret.append((char) c1);
			}
			if (++i >= len)
				continue;
			c1 = data[i];
			if (61 == c1)
				break;
			c1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
					.indexOf((char) c1);
			c = c << 6 & 0xC0 | c1;
			ret.append((char) c);
		}

		return ret.toString();
	}

	public static final String[] toLowerCaseWordArray(String text) {
		if ((text == null) || (text.length() == 0))
			return new String[0];
		ArrayList wordList = new ArrayList();
		BreakIterator boundary = BreakIterator.getWordInstance();
		boundary.setText(text);
		int start = 0;
		for (int end = boundary.next(); end != -1; end = boundary.next()) {
			String tmp = text.substring(start, end).trim();
			tmp = replace(tmp, "+", "");
			tmp = replace(tmp, "/", "");
			tmp = replace(tmp, "\\", "");
			tmp = replace(tmp, "#", "");
			tmp = replace(tmp, "*", "");
			tmp = replace(tmp, ")", "");
			tmp = replace(tmp, "(", "");
			tmp = replace(tmp, "&", "");
			if (tmp.length() > 0)
				wordList.add(tmp);
			start = end;
		}

		return ((String[]) wordList.toArray(new String[wordList.size()]));
	}

	public static final String randomString(int length) {
		if (length < 1)
			return null;
		char[] randBuffer = new char[length];
		for (int i = 0; i < randBuffer.length; ++i) {
			randBuffer[i] = g[f.nextInt(71)];
		}
		return new String(randBuffer);
	}


	public static final String zeroPadString(String string, int length) {
		if ((string == null) || (string.length() > length)) {
			return string;
		}
		StringBuffer buf = new StringBuffer(length);
		buf.append(h, 0, length - string.length()).append(string);
		return buf.toString();
	}

	public static final String formatJavaName(String name,
			boolean firstCharUpperCase) {
		if ((name == null) || (name.length() <= 1))
			return name;
		StringTokenizer tokenizer = new StringTokenizer(name, "-_");
		StringBuffer tmp = new StringBuffer();
		while (tokenizer.hasMoreTokens()) {
			String token = tokenizer.nextToken();
			tmp.append(Character.toUpperCase(token.charAt(0))).append(
					token.substring(1));
		}
		if (!(firstCharUpperCase)) {
			String ch = String.valueOf(Character.toLowerCase(tmp.charAt(0)));
			tmp.replace(0, 1, ch);
		}
		return tmp.toString();
	}

	public static final String upperFirst(String name) {
		StringBuffer sb = new StringBuffer();
		sb.append(Character.toUpperCase(name.charAt(0))).append(
				name.substring(1));
		return sb.toString();
	}

	public static final String upperFirstFormatJavaName(String name) {
		return formatJavaName(name, true);
	}

	public static final String lowerFirst(String name) {
		StringBuffer sb = new StringBuffer();
		sb.append(Character.toLowerCase(name.charAt(0))).append(
				name.substring(1));
		return sb.toString();
	}

	public static final String lowerFirstFormatJavaName(String name) {
		return formatJavaName(name, true);
	}

	public static final String formatJavaName(String name) {
		return formatJavaName(name, false);
	}

	public static String join(String seperator, String[] strings) {
		int length = strings.length;
		if (length == 0)
			return "";
		StringBuffer buf = new StringBuffer(length * strings[0].length())
				.append(strings[0]);
		for (int i = 1; i < length; ++i) {
			buf.append(seperator).append(strings[i]);
		}
		return buf.toString();
	}

	public static String join(String seperator, Iterator objects) {
		StringBuffer buf = new StringBuffer();
		buf.append(objects.next());
		while (objects.hasNext()) {
			buf.append(seperator).append(objects.next());
		}
		return buf.toString();
	}

	public static String Array2String(String[] values) {
		return join(",", values);
	}

	private static final byte a(char ch) {
		switch (ch) {
		case '0':
			return 0;
		case '1':
			return 1;
		case '2':
			return 2;
		case '3':
			return 3;
		case '4':
			return 4;
		case '5':
			return 5;
		case '6':
			return 6;
		case '7':
			return 7;
		case '8':
			return 8;
		case '9':
			return 9;
		case 'a':
			return 10;
		case 'b':
			return 11;
		case 'c':
			return 12;
		case 'd':
			return 13;
		case 'e':
			return 14;
		case 'f':
			return 15;
		case ':':
		case ';':
		case '<':
		case '=':
		case '>':
		case '?':
		case '@':
		case 'A':
		case 'B':
		case 'C':
		case 'D':
		case 'E':
		case 'F':
		case 'G':
		case 'H':
		case 'I':
		case 'J':
		case 'K':
		case 'L':
		case 'M':
		case 'N':
		case 'O':
		case 'P':
		case 'Q':
		case 'R':
		case 'S':
		case 'T':
		case 'U':
		case 'V':
		case 'W':
		case 'X':
		case 'Y':
		case 'Z':
		case '[':
		case '\\':
		case ']':
		case '^':
		case '_':
		case '`':
		}

		return 0;
	}

	public static String toLowerCase(String value) {
		if (isBlank(value))
			return value;
		return value.trim().toLowerCase();
	}
}